package screens 
{
	import Buttons.PlayButton;
	import Buttons.Tool;
	import Entities.InstrumentLayer;
	import Entities.InstrumentMC;
	import Entities.Note;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.display.CapsStyle;
	import flash.display.JointStyle;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.StyleSheet;
	import flash.text.TextField;
	import tools.CopyNotesTool;
	import tools.DrawNotesTool;
	import tools.INoteTool;
	import tools.PanScreenTool;
	/**
	 * ...
	 * @author Andy Wolff
	 */
	public class NoteCanvas extends MovieClip
	{
		//[Embed(source = '../images/Buttons/tracks.png')] private var tracksIMG:Class;
		//[Embed(source = '../images/Buttons/timeline.png')] private var timelineIMG:Class;
		
		[Embed(source = '../images/Buttons/toBeginning.png')] private var toBeginningIMG:Class;
		[Embed(source = '../images/Buttons/rewind.png')] private var rewindIMG:Class;
		[Embed(source = '../images/Buttons/play.png')] private var playIMG:Class;
		[Embed(source = '../images/Buttons/pause.png')] private var pauseIMG:Class;
		[Embed(source = '../images/Buttons/fastForward.png')] private var fastForwardIMG:Class;
		[Embed(source = '../images/Buttons/toEnd.png')] private var toEndIMG:Class;
		
		[Embed(source = '../images/Buttons/undo.png')] private var undoIMG:Class;
		[Embed(source = '../images/Buttons/redo.png')] private var redoIMG:Class;
		
		private var view:MainScreen;
		public var tabs:ToolsTabs;
		private var timeline:MovieClip;
		
		private var instruments:Array;
		public function getInstruments():Array { return instruments; }
		//private static var currentInstrument:InstrumentLayer;
		private var instrument_index:int = 0;
		private var previousState:Array, previousIndex:int;
		public function getCurrentInstrument():InstrumentLayer { 
			return instruments[instrument_index]; 
			}
		public function getInstrument(index:int):InstrumentLayer { return instruments[index]; }
		public function selectInstrument(IL:InstrumentLayer):void { 
			instrument_index = instruments.indexOf(IL);
			}
		
		private var drawNotesTool:DrawNotesTool;
		private var copyNotesTool:CopyNotesTool;
		private var panScreenTool:PanScreenTool;
		public function currentNoteTool():INoteTool { 
			var whichTool:int = view.whichTool(); 
			if (whichTool == Tool.COPY || whichTool==Tool.MOVE) return copyNotesTool;
			if (whichTool == Tool.DRAW || whichTool == Tool.ERASE) return drawNotesTool;
			if (whichTool == Tool.PAN) return panScreenTool;
			return drawNotesTool; //default
		}
		
		public function whichTool():int { return view.whichTool(); }
		
		private var buttons:Array;
		private var playBtn:PlayButton, playMC:MovieClip, pauseMC:MovieClip;
		private var isPlaying:Boolean=false;
		public function togglePlaying():void { 
			if (isPlaying) { isPlaying = false; playMC.visible = true; pauseMC.visible = false; }
			else { isPlaying = true; playMC.visible = false; pauseMC.visible = true; }
		}
		
		public static var playPos:Number = 0;
		static private var viewPos:Number = 0;
		public static const viewWidth:int = 553, maxViewPos:int = 2450;
		public function getViewPos():Number { return viewPos; }
		public function setView(view:Number):void { viewPos = Math.max(0,Math.min(view,maxViewPos)); timeline.scrollRect= new Rectangle(viewPos, 0, viewWidth, 27); }
		public function panView(pan:Number):void { viewPos += pan; viewPos = Math.max(0, Math.min(viewPos,maxViewPos)); timeline.scrollRect = new Rectangle(viewPos, 0, viewWidth, 27); }
		public function getPlayArea():Rectangle { return new Rectangle(viewPos, playPos, viewWidth, 352); }
		
		private var canvasX:int=20, canvasY:int=58, canvasW:int=viewWidth, canvasH:int=352;
		
		public function NoteCanvas(view:MainScreen) 
		{
			this.view = view;
			this.addEventListener(Event.ENTER_FRAME, draw);
			
			timeline = new MovieClip;
			var t:TextField;
			for (var i:int = 0; i < 61; i++) {
				t = new TextField();
				timeline.addChild(t);
				t.x = 50*i; t.y = 7-20; 
				t.text = "" + i;
				t.textColor = 0x000000; 
				t.scaleX = 3; t.scaleY = 3;
				t.mouseEnabled = false; t.tabEnabled = false; t.selectable = false;
				t.x -= 16;
			}
			addChild(timeline);
			timeline.scrollRect = new Rectangle(0, 0, viewWidth, 27);
			timeline.x = 20; timeline.y = 20;
			
			
			instruments = new Array();
			var il:InstrumentLayer;
			il = new InstrumentLayer(this, 0xBBBBFF, 0);
			instruments.push(il);
			selectInstrument(il);
			il = new InstrumentLayer(this, 0xFF0000, 1);
			il.visible = false;
			instruments.push(il);
			il = new InstrumentLayer(this, 0x22EE44, 2);
			il.visible = false;
			instruments.push(il);
			
			tabs=new ToolsTabs(this);
			view.addChild(tabs);
			
			saveState();
			
			view.main.stage.addEventListener(KeyboardEvent.KEY_DOWN, this.keypress);
			addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
			addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
			addEventListener(MouseEvent.MOUSE_UP, mouseUp);
			addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
			
						
			drawNotesTool = new DrawNotesTool(this);
			copyNotesTool = new CopyNotesTool(this);
			panScreenTool = new PanScreenTool(this);
			
			addEventListener(Event.ENTER_FRAME, step);
			
			//buttons
			var last:MovieClip;
			i = 0;
			buttons = new Array(5);
			
			var toBeginningBtn:PlayButton = new PlayButton(this,i);
			toBeginningBtn.addChild(new toBeginningIMG());
			//Main.center2(toBeginningBtn, width, 0);
			toBeginningBtn.y = 470-8 - toBeginningBtn.height;
			toBeginningBtn.x = 20;
			addChild(toBeginningBtn);
			last = toBeginningBtn; 
			PlayButton.TOBEGINNING = i;
			buttons[i] = last;
			i++;
			
			var rewindBtn:PlayButton = new PlayButton(this,i);
			rewindBtn.addChild(new rewindIMG());
			//Main.center2(rewindBtn, width, 0);
			rewindBtn.y = 470-8 - rewindBtn.height;
			rewindBtn.x = last.x+last.width+20;
			addChild(rewindBtn);
			last = rewindBtn; 
			PlayButton.REWIND = i;
			buttons[i] = last;
			i++;
			
			playBtn = new PlayButton(this, i);
			playMC = new MovieClip(); playMC.addChild(new playIMG());
			playBtn.addChild(playMC);
			pauseMC = new MovieClip(); pauseMC.addChild(new pauseIMG());
			playBtn.addChild(pauseMC);
			pauseMC.visible = false;
			//Main.center2(playBtn, width, 0);
			playBtn.y = 470-8 - playBtn.height;
			playBtn.x = last.x+last.width+20;
			addChild(playBtn);
			last = playBtn; 
			PlayButton.PLAY = i;
			buttons[i] = last;
			i++;
			
			var fastForwardBtn:PlayButton = new PlayButton(this,i);
			fastForwardBtn.addChild(new fastForwardIMG());
			//Main.center2(fastForwardBtn, width, 0);
			fastForwardBtn.y = 470-8 - fastForwardBtn.height;
			fastForwardBtn.x = last.x+last.width+20;
			addChild(fastForwardBtn);
			last = fastForwardBtn; 
			PlayButton.FASTFORWARD = i;
			buttons[i] = last;
			i++;
			
			var toEndBtn:PlayButton = new PlayButton(this,i);
			toEndBtn.addChild(new toEndIMG());
			//Main.center2(toEndBtn, width, 0);
			toEndBtn.y = 470-8 - toEndBtn.height;
			toEndBtn.x = last.x+last.width+20;
			addChild(toEndBtn);
			last = toEndBtn; 
			PlayButton.TOEND = i;
			buttons[i] = last;
			i++;
			
			var undoBtn:PlayButton = new PlayButton(this,i);
			undoBtn.addChild(new undoIMG());
			//Main.center2(undoBtn, width, 0);
			undoBtn.y = 470-8 - undoBtn.height;
			undoBtn.x = last.x+last.width+20;
			addChild(undoBtn);
			last = undoBtn; 
			PlayButton.UNDO = i;
			buttons[i] = last;
			i++;
			
			var redoBtn:PlayButton = new PlayButton(this,i);
			redoBtn.addChild(new redoIMG());
			//Main.center2(redoBtn, width, 0);
			redoBtn.y = 470-8 - redoBtn.height;
			redoBtn.x = last.x+last.width+20;
			addChild(redoBtn);
			last = redoBtn; 
			PlayButton.REDO = i;
			buttons[i] = last;
			i++;
			redoBtn.transform.colorTransform = new ColorTransform(0.5, 0.5, 0.5);
		}
		
		private var mouseclicked:Boolean = false;
		private var drawnlines:Array = null;
		private var drawnlinespos:int = 0;
		private var currentNote:Note;
		public function mouseDown(e:MouseEvent):void {
			if (e.localX >= canvasX && e.localX <= canvasX + canvasW && e.localY >= canvasY && e.localY <= canvasY + canvasH) currentNoteTool().mouseDown(e);
			else currentNoteTool().end();
		}
		
		public function mouseMove(e:MouseEvent):void {
			if (e.localX >= canvasX && e.localX <= canvasX + canvasW && e.localY >= canvasY && e.localY <= canvasY + canvasH) currentNoteTool().mouseMove(e);
			else currentNoteTool().end();
		}
		
		public function mouseUp(e:MouseEvent):void {
			if (e.localX >= canvasX && e.localX <= canvasX + canvasW && e.localY >= canvasY && e.localY <= canvasY + canvasH) currentNoteTool().mouseUp(e);
			else currentNoteTool().end();
		}
		
		public function mouseOut(e:MouseEvent):void {
			currentNoteTool().end();
		}
		
		//temp
		public function rewind(amount:int):void { playPos -= amount; playPos = Math.max(0, playPos); if (playPos < viewPos) panView(playPos - viewPos); }
		public function fastForward(amount:int):void { playPos += amount; playPos = Math.min(playPos, maxViewPos+viewWidth);  if (playPos - viewPos > viewWidth) panView(playPos - viewPos - viewWidth); }
		public function keypress(k:KeyboardEvent):void {
			if (k.keyCode == 37) rewind(50);//left
			if (k.keyCode == 39) fastForward(50); //right
			
			//if (k.keyCode >= 49 && k.keyCode<=56 ) makeNote(k.keyCode-49);
			
		}
		
		public function buttonPressed(which:int):void {
			switch (which) {
				case (PlayButton.TOBEGINNING):  
					setView(0); playPos = 0;
				break;
				case (PlayButton.TOEND):  
					setView(maxViewPos); playPos = maxViewPos+viewWidth;
				break;
				case (PlayButton.PLAY):
					togglePlaying();
				break;
				case (PlayButton.UNDO):
					loadState();
				break;
			}
		}
		
		public function buttonHeld(which:int):void {
			switch (which) {
				case (PlayButton.REWIND):  
					rewind(10);
				break;
				case (PlayButton.FASTFORWARD):  
					fastForward(10);
				break;
			}
		}
		
		public function step(e:Event):void {
			if (isPlaying) fastForward(4);
		}
		
		public function draw(e:Event):void {
			//timeline.scrollRect= new Rectangle(timeline.scrollRect.x+2, 0, viewWidth, 27);
			graphics.clear();
			graphics.beginFill(0x888888, 1);
			graphics.drawRect(20, 20, viewWidth, 27); //draw timeline bg
			graphics.drawRect(canvasX, canvasY, canvasW, canvasH); //draw canvas
			graphics.endFill();
			
			//canvas outline
			graphics.lineStyle(4, 0xAAAAAA,1,false,"normal",CapsStyle.SQUARE,JointStyle.MITER);
			graphics.moveTo(canvasX, canvasY);
			graphics.lineTo(canvasX + canvasW, canvasY);
			graphics.lineTo(canvasX + canvasW, canvasY + canvasH);
			graphics.lineTo(canvasX, canvasY + canvasH);
			graphics.lineTo(canvasX, canvasY);
			
			//note rows
			graphics.lineStyle(2, 0xAAAAAA,1,false,"normal",CapsStyle.SQUARE,JointStyle.MITER);
			for (var i:int = canvasH/8; i < canvasH; i += canvasH / 8) {
				graphics.moveTo(canvasX, canvasY + i);
				graphics.lineTo(canvasX + canvasW, canvasY + i);
			}
			
			if (instruments != null) for each (var I:InstrumentLayer in instruments) if (I != null && I != getCurrentInstrument() && I.visible) I.draw(graphics);
			getCurrentInstrument().draw(graphics);
			
			//draw notes stuff
			drawNotesTool.draw(graphics);
			
			//draw the playhead
			graphics.lineStyle(2, 0x20FB00, 0.8, false, "normal", CapsStyle.SQUARE, JointStyle.MITER);
			graphics.moveTo(canvasX + playPos - viewPos, 20);
			if (playPos>=viewPos) graphics.lineTo(canvasX + playPos - viewPos, canvasY+canvasH);
		}
		
		static public function getNoteX(localX:int):int {
			return localX + viewPos - 20;
		}
		static public function getNoteRow(atY:int):int {
			return Math.min(7, Math.floor((atY - 56) / 44));
		}
		static public function snapToNoteRow(atY:int):int {
			return Math.min(7, Math.floor((atY - 56) / 44)) * 44 + 22 + 56;
		}
		
		public function saveState():void {
			previousIndex = instruments.indexOf(getCurrentInstrument(), 0);
			previousState = new Array();
			
			for (var i:int = 0; i < instruments.length; i++) {
				var il:InstrumentLayer = instruments[i];
				var newIL:InstrumentLayer = new InstrumentLayer(this, il.color,il.type);
				newIL.visible = il.visible;
				newIL.mergeInstrument(il);
				previousState.push(newIL);
			}
			
		}
		
		
		public function loadState():void {
			var newPrevious:Array = instruments, newPreviousIndex:int = instrument_index;
			instruments = new Array();
			var MCs:Array = new Array();
			
			for (var i:int = 0; i < previousState.length; i++) {
				var il:InstrumentLayer = previousState[i] as InstrumentLayer;
				var newIL:InstrumentLayer = new InstrumentLayer(this, il.color,il.type);
				newIL.visible = il.visible;
				newIL.mergeInstrument(il);
				instruments.push(newIL);
			}
			
			selectInstrument(getInstrument(previousIndex));
			previousState = newPrevious; previousIndex = newPreviousIndex;
			
			tabs.tab3.restart();
		}
	}

}